#!/bin/bash
#October, 2022
# This alpha version contains verbose output for debugging purposes.
# Constants
# ishare2 configuration
CHANNEL="alpha"
ISHARE2_DIR="/opt/ishare2/cli"
SOURCES="$ISHARE2_DIR/sources.list"
VERSION="v1.7.4"

# Colors
RED='\033[31m'
YELLOW='\033[1;33m'
GREEN='\033[32m'
NO_COLOR='\033[0m'

function check_ishare2_dir() {
    # check if ishare2 directory exists otherwise create it
    if [[ ! -d $ISHARE2_DIR ]]; then
        create_ishare2_dir
    fi
}

# set max log file lines to 1000
function set_max_log_lines() {
    if [[ -f $ISHARE2_DIR/logs.txt ]]; then
        if [[ $(wc -l <"$ISHARE2_DIR/logs.txt") -gt 1000 ]]; then
            tail -n 1000 $ISHARE2_DIR/logs.txt >$ISHARE2_DIR/tmp.txt
            mv $ISHARE2_DIR/tmp.txt $ISHARE2_DIR/logs.txt
        fi
    fi
}

function check_aria2() {
    # Check if aria2c is installed
    if ! command -v aria2c &>/dev/null; then
        echo -e "${YELLOW}[+] aria2c is not installed.${NO_COLOR}"
        echo -e "${YELLOW}[+] Installing aria2c...${NO_COLOR}"
        if ! apt-get install -y aria2 &>/dev/null; then
            echo -e "${RED}[-] Failed to install aria2c.${NO_COLOR}"
            echo -e "${RED}[-] ishare2 requires aria2c to work properly.${NO_COLOR}"
            echo -e "${RED}[-] Please install aria2c manually and try again.${NO_COLOR}"
            echo -e "Use: ${YELLOW}sudo apt-get install -y aria2${NO_COLOR}"
            echo -e "${RED}[-] Exiting...${NO_COLOR}"
            exit 1
        fi
        echo -e "${GREEN}[+] Done.${NO_COLOR}"
    fi
}

function create_ishare2_dir() {
    echo -e "${YELLOW}[+] Creating ishare2 directory...${NO_COLOR}"
    if ! mkdir -p $ISHARE2_DIR 2>/dev/null; then
        error_message=$(mkdir -p $ISHARE2_DIR 2>&1 >/dev/null)
        if [[ $error_message == *"Permission denied"* ]]; then
            echo -e "${RED}[-] Failed to create ishare2 directory: Permission denied.${NO_COLOR}"
        else
            echo -e "${RED}[-] Failed to create ishare2 directory. Error: $error_message${NO_COLOR}"
        fi
        exit 1
    fi
    echo -e "${GREEN}[+] Done.${NO_COLOR}"
}

function fetch_sources() {
    check_ishare2_dir
    echo -e "${YELLOW}[+] Fetching sources...${NO_COLOR}"
    curl -s -o $SOURCES https://raw.githubusercontent.com/pnetlabrepo/ishare2/$CHANNEL/sources.list
    # Check if curl command failed
    if [[ ! -f $SOURCES ]]; then
        echo -e "${RED}[-] Failed to fetch sources.${NO_COLOR}"
        exit 1
    fi
    echo -e "${GREEN}[+] Done.${NO_COLOR}"
}

download_file_aria2() {
    url="$1"
    output_dir="$2"
    output_name="$3"
    echo -e "${YELLOW} [+] Downloading file from $url... ${NO_COLOR}"
    rm -f error.log
    if aria2c --download-result=hide --allow-overwrite=true --dir="$output_dir" --out="$output_name" --log="error.log" "$url"; then
        echo -e "${GREEN} [+] The file has been downloaded successfully to $output_dir. ${NO_COLOR}"
        rm -f error.log
    else
        echo -e "${RED} [-] Error: Unable to download the file. Check the error.log file for more information.${NO_COLOR}"
        exit 1
    fi
}

download_file_curl() {
    # Create the directory if it does not exist
    mkdir -p $ISHARE2_DIR/tmp
    # Create the file if it does not exist
    touch $ISHARE2_DIR/tmp/curl_error
    local url="$1"
    local output="$2"
    echo -e "${YELLOW} [+] Downloading file from $url... ${NO_COLOR}" >$ISHARE2_DIR/logs.txt
    if curl -s -o "$output" "$url" 2>$ISHARE2_DIR/tmp/curl_error; then
        echo -e "${GREEN} [+] The file has been downloaded successfully to $output. ${NO_COLOR}" >$ISHARE2_DIR/logs.txt
        rm -f $ISHARE2_DIR/tmp/curl_error
    else
        echo -e "${RED} [-] Error: Unable to download the file. ${NO_COLOR}"
        # Read the error message from the curl_error file
        ERROR_MESSAGE=$(cat $ISHARE2_DIR/tmp/curl_error)
        # Print the error message
        echo -e "${RED} [-] Logs:\n $ERROR_MESSAGE ${NO_COLOR}"
        exit 1
    fi
}

download_file_wget() {
    # Create the directory if it does not exist
    mkdir -p $ISHARE2_DIR/tmp
    # Create the file if it does not exist
    touch $ISHARE2_DIR/tmp/wget_error
    local url="$1"
    local output="$2"
    echo -e "${YELLOW} [+] Downloading file from $url... ${NO_COLOR}" >$ISHARE2_DIR/logs.txt
    if wget -q -O "$output" "$url" 2>$ISHARE2_DIR/tmp/wget_error; then
        echo -e "${GREEN} [+] The file has been downloaded successfully to $output. ${NO_COLOR}" >$ISHARE2_DIR/logs.txt
        rm -f $ISHARE2_DIR/tmp/wget_error
    else
        echo -e "${RED} [-] Error: Unable to download the file. ${NO_COLOR}"
        # Read the error message from the wget_error file
        ERROR_MESSAGE=$(cat $ISHARE2_DIR/tmp/wget_error)
        # Print the error message
        echo -e "${RED} [-] Logs:\n $ERROR_MESSAGE ${NO_COLOR}"
        exit 1
    fi
}

download_file() {
    # Check if aria2c is installed
    if command -v aria2c &>/dev/null; then
        download_file_aria2 "$1" "$2" "$3"
    else
        path="$2/$3"
        download_file_wget "$1" "$path"
    fi
}

function set_url_constants() {
    # Check if sources file does not exist
    if [[ ! -f $SOURCES ]]; then
        echo -e "${YELLOW}[!] Sources file does not exist.${NO_COLOR}"
        fetch_sources
    fi
    # Check if sources file is empty
    if [[ ! -s $SOURCES ]]; then
        echo -e "${YELLOW}[!] Sources file is empty.${NO_COLOR}"
        fetch_sources
    fi
    # Check if sources file is corrupted
    if ! grep -q "URL_ID_LIST=" $SOURCES; then
        echo -e "${YELLOW}[!] Sources file is corrupted.${NO_COLOR}"
        fetch_sources
    fi
    # Check if sources file is older than 1 day
    if [[ $(find $SOURCES -mtime +1) ]]; then
        echo -e "${YELLOW}[!] Sources file is older than 1 day.${NO_COLOR}"
        fetch_sources
    fi

    source $SOURCES
}

function check_user_is_root() {
    if ! [[ "$(id -u)" == 0 ]]; then
        user=$(whoami)
        echo -e "${RED}[!] This script requires root privileges to be executed. The current user, "$user", does not have enough permissions. Please, switch to the root user to run the script.${NO_COLOR}"
        exit 1
    fi
}

function download_files_lists() {
    # Attempt to make ishare2 basic functionality as offline as possible
    # If files are available locally, use them
    # If files are not available locally or are too old, download them from the internet
    # If internet is not available, use the last available version of the files
    # If "id_list" file exists, don't download it again unless it is older than 1 day
    if [ -f $ISHARE2_DIR"/id_list" ]; then
        if [ $(find $ISHARE2_DIR"/id_list" -mtime +1) ]; then
            echo -e "${YELLOW} [!] The list of Google Spreadsheets IDs is older than 1 day. Updating... ${NO_COLOR}" >$ISHARE2_DIR/logs.txt
            download_file_curl $URL_ID_LIST $ISHARE2_DIR"/id_list"
        else
            echo -e "${GREEN} [+] The list of Google Spreadsheets IDs is up to date. ${NO_COLOR}" >$ISHARE2_DIR/logs.txt
        fi
    else
        echo -e "${YELLOW} [!] The list of Google Spreadsheets IDs does not exist. Downloading... ${NO_COLOR}"
        download_file_curl $URL_ID_LIST $ISHARE2_DIR"/id_list"
    fi
    # Source the id_list file
    source $ISHARE2_DIR"/id_list"
    # Define the URLs
    # $GOOGLE is defined in the id_list file. It is the Google Spreadsheets ID
    URL_PREFIX='https://docs.google.com/spreadsheets/d/e/'$GOOGLE'/pub?gid='
    URL_POSTFIX='&single=true&output=csv'
    # $BIN, $QEMU, $DYNAMIPS are defined in the id_list file. They are the Google Spreadsheets IDs
    BIN_URL=$URL_PREFIX$BIN$URL_POSTFIX
    QEMU_URL=$URL_PREFIX$QEMU$URL_POSTFIX
    DYNAMIPS_URL=$URL_PREFIX$DYNAMIPS$URL_POSTFIX
    # If csv files /list of images exist, don't download them again unless they are older than 1 day
    fetch_lists "BIN" $BIN_URL
    fetch_lists "QEMU" $QEMU_URL
    fetch_lists "DYNAMIPS" $DYNAMIPS_URL
}

fetch_lists() {
    TYPE=$1
    URL=$2
    CHECK_DATE=${3:-true} # default value is true
    if [ -f $ISHARE2_DIR"/$TYPE.csv" ]; then
        if [[ "$CHECK_DATE" == "true" ]] && [ $(find $ISHARE2_DIR"/$TYPE.csv" -mtime +1) ]; then
            echo -e "${YELLOW} [!] The list of $TYPE images is older than 1 day. Updating ${NO_COLOR}" >$ISHARE2_DIR/logs.txt
            download_file_wget $URL $ISHARE2_DIR"/$TYPE.csv"
        elif [[ "$CHECK_DATE" == "false" ]]; then
            echo -e "${GREEN} [+] Downloading the list of $TYPE images. ${NO_COLOR}"
            download_file_wget $URL $ISHARE2_DIR"/$TYPE.csv"
        else
            echo -e "${GREEN} [+] The list of $TYPE images is up to date. ${NO_COLOR}" >$ISHARE2_DIR/logs.txt
        fi
    else
        echo -e "${YELLOW} [!] The list of images $TYPE does not exist. ${NO_COLOR}"
        download_file_wget $URL $ISHARE2_DIR"/$TYPE.csv"
    fi
}

manual_sources_update() {
    echo -e "${YELLOW} [+] Updating the sources file. ${NO_COLOR}"
    fetch_sources
    if [ -f $SOURCES ]; then
        echo -e "${GREEN} [+] The sources file has been updated. ${NO_COLOR}"
    else
        echo -e "${RED} [!] The sources file could not be updated. ${NO_COLOR}"
    fi
    echo -e "${YELLOW} [+] Updating the lists of images. ${NO_COLOR}"
    # Source the id_list file
    source $ISHARE2_DIR"/id_list"
    # Define the URLs
    # $GOOGLE is defined in the id_list file. It is the Google Spreadsheets ID
    URL_PREFIX='https://docs.google.com/spreadsheets/d/e/'$GOOGLE'/pub?gid='
    URL_POSTFIX='&single=true&output=csv'
    # $BIN, $QEMU, $DYNAMIPS are defined in the id_list file. They are the Google Spreadsheets IDs
    BIN_URL=$URL_PREFIX$BIN$URL_POSTFIX
    QEMU_URL=$URL_PREFIX$QEMU$URL_POSTFIX
    DYNAMIPS_URL=$URL_PREFIX$DYNAMIPS$URL_POSTFIX
    fetch_lists "BIN" $BIN_URL false
    fetch_lists "QEMU" $QEMU_URL false
    fetch_lists "DYNAMIPS" $DYNAMIPS_URL false
}

function get_server_platform() {
    grep -q vmx /proc/cpuinfo && echo -n vmx >/opt/unetlab/platform
    grep -q svm /proc/cpuinfo && echo -n svm >/opt/unetlab/platform

    platform=$(cat /opt/unetlab/platform)

    if [[ $platform == "vmx" ]]; then YML_DIR="/opt/unetlab/html/templates/intel/"; fi
    if [[ $platform == "svm" ]]; then YML_DIR="/opt/unetlab/html/templates/amd/"; fi
}

function set_yml_template_folder_location() {
    data=$(mysql -uroot -ppnetlab -D pnetlab_db -e "SELECT control_value FROM control WHERE control_value>1;" 2>/dev/null)
    data_array=($data)
    pnetlab_version=${data_array[1]}

    if [[ $pnetlab_version == "4.2.10" ]] || [[ $pnetlab_version == "5.0.1" ]]; then
        YML_DIR="/opt/unetlab/html/templates/"
    fi

    if [[ $pnetlab_version == *5.2* ]] || [[ $pnetlab_version == *5.3* ]] || [[ $pnetlab_version == *6.* ]]; then
        get_server_platform
    fi
}

function mylabs_get_lab_list_just_for_only_readable_labs() {
    LABS_DIR=$1

    # Added some correction when "/" is not found at the end of the provided path (LABS_DIR)
    if ! [[ ${LABS_DIR: -1} == "/" ]]; then LABS_DIR=$LABS_DIR/; fi

    if ! [[ -d $LABS_DIR ]]; then
        echo "Folder $LABS_DIR has not been found"
        echo "Check your full path to the labs"
        exit 0
    fi

    if [[ -z "$(ls -A "$LABS_DIR")" ]]; then
        echo "No labs found at $LABS_DIR folder in server"
        exit 0
    fi

    counter_all_labs_installed_on_server=0
    for file in "$LABS_DIR"*; do
        if [[ -d $file ]]; then continue; fi # Avoiding folders
        counter_all_lab
        s_installed_on_server=$((counter_all_labs_installed_on_server + 1))
    done

    echo -e "Labs inside $LABS_DIR folder in VM: $counter_all_labs_installed_on_server"

    declare -a readableLabsArray=()
    declare -a authorLabsArray=()

    for file in "$LABS_DIR"*; do
        if [[ -d $file ]]; then continue; fi # Avoiding folders
        check=$(grep -Pio 'encoding="UTF-8"' "$file")
        SUB="encoding"
        if [[ $check == *"$SUB"* ]]; then
            readableLabsArray+=("$file")
            # Get Author name list
            author_lab_name=$(grep -Pio '.*author="\K[^"]*' "$file" | sort -u)
            if [[ -z $author_lab_name ]]; then # Author name not specified
                author_lab_name=N/A
            fi
            authorLabsArray+=("$author_lab_name")
        fi
    done

    echo "Labs in plain text: ${#readableLabsArray[@]}"

    if [[ ${#readableLabsArray[@]} -eq 0 ]]; then
        STR="No readable labs have been found so there is no way to continue with this command"
        echo -e "${RED}[-]$STR\033[0m"
        exit 0
    fi

    echo -e "\nList\n"

    counter_for_readable_labs=0

    for f in "${readableLabsArray[@]}"; do
        counter_for_readable_labs=$((counter_for_readable_labs + 1))
        echo -e "$counter_for_readable_labs) ${f##*/} - ${authorLabsArray[$((counter_for_readable_labs - 1))]}"
    done

    STR1="ishare2 mylabs <path> <number>"
    STR2="ishare2 mylabs <path> all"
    echo -e "\nTo install images for a specific lab, use the following command:\n\033[32m$STR1\033[0m"
    echo -e "\nTo install images for all of the labs, use the following command:\n\033[32m$STR2\033[0m"
}

function mylabs_install_lab_images_just_for_only_readable_labs() {
    LABS_DIR=$1
    NUMBER=$2

    # Added some correction when "/" is not found at the end of the provided path (LABS_DIR)
    if ! [[ ${LABS_DIR: -1} == "/" ]]; then LABS_DIR=$LABS_DIR/; fi

    if ! [[ -d $LABS_DIR ]]; then
        echo "Folder $LABS_DIR has not been found"
        echo "Check your full path to the labs"
        exit 0
    fi

    if [[ -z "$(ls -A "$LABS_DIR")" ]]; then
        echo "No labs found at $LABS_DIR folder in server"
        exit 0
    fi

    declare -a readableLabsArray=()
    for file in "$LABS_DIR"*; do
        if [[ -d $file ]]; then continue; fi # Avoiding folders
        check=$(grep -Pio 'encoding="UTF-8"' "$file")
        SUB="encoding"
        if [[ $check == *"$SUB"* ]]; then
            readableLabsArray+=("$file")
        fi
    done

    counter_for_readable_labs=0
    for f in "${readableLabsArray[@]}"; do
        counter_for_readable_labs=$((counter_for_readable_labs + 1))
    done

    if [[ ${#readableLabsArray[@]} -eq 0 ]]; then
        STR="No readable labs have been found so there is no way to continue with this command"
        echo -e "${RED}[-]$STR\033[0m"
        exit 0
    fi

    if [[ $NUMBER -gt $counter_for_readable_labs || $NUMBER -le 0 ]]; then
        if [[ $counter_for_readable_labs -eq 1 ]]; then
            STR="Last parameter must be 1 because you have only one lab"
            echo -e "${YELLOW}$STR${NO_COLOR}"
        else
            STR="Last parameter must be a number between 1 and $counter_for_readable_labs"
            echo -e "${YELLOW}$STR${NO_COLOR}"
        fi

        echo -e
        mylabs_get_lab_list_just_for_only_readable_labs $1
        exit 0
    fi

    file=${readableLabsArray[$((NUMBER - 1))]}
    echo -e "File selected: $file"

    #echo -e "\nIOL images"
    iol_images=$(grep -Pio 'type="iol".*image="\K[^"]*' "$file" | sort -u)
    #echo "$iol_images"
    echo "$iol_images" >/opt/unetlab/labs/iol_images.txt

    #echo -e "\nDynamips images"
    dynamips_images=$(grep -Pio 'type="dynamips".*image="\K[^"]*' "$file" | sort -u)
    #echo "$dynamips_images"
    echo "$dynamips_images" >/opt/unetlab/labs/dynamips_images.txt

    #echo -e "\nQemu images"
    qemu_images=$(grep -Pio 'type="qemu".*image="\K[^"]*' "$file" | sort -u)
    #echo "$qemu_images"
    echo "$qemu_images" >/opt/unetlab/labs/qemu_images.txt

    #echo -e "\nDocker images"
    docker_images=$(grep -Pio 'type="docker".*image="\K[^"]*' "$file" | sort -u)
    echo "$docker_images" >/opt/unetlab/labs/docker_images.txt

    filename1_iol_images=/opt/unetlab/labs/iol_images.txt
    filename2_dynamips_images=/opt/unetlab/labs/dynamips_images.txt
    filename3_qemu_images=/opt/unetlab/labs/qemu_images.txt
    filename4_docker_images=/opt/unetlab/labs/docker_images.txt

    BIN_FLAG=0
    if ! grep -q '[^[:space:]]' $filename1_iol_images; then BIN_FLAG=1; fi

    DYNAMIPS_FLAG=0
    if ! grep -q '[^[:space:]]' $filename2_dynamips_images; then DYNAMIPS_FLAG=1; fi

    QEMU_FLAG=0
    if ! grep -q '[^[:space:]]' $filename3_qemu_images; then QEMU_FLAG=1; fi

    DOCKER_FLAG=0
    if ! grep -q '[^[:space:]]' $filename4_docker_images; then DOCKER_FLAG=1; fi

    echo -e "\nImages found on lab\n"

    echo -e "${GREEN}--- bin images ---${NO_COLOR}"
    if [[ BIN_FLAG -eq 1 ]]; then
        echo No bin images found
    else
        n=1
        while read -r line; do
            echo "File $n : $line"
            n=$((n + 1))
        done <$filename1_iol_images
    fi

    echo -e "\n${GREEN}--- dynamips images ---${NO_COLOR}"
    if [[ DYNAMIPS_FLAG -eq 1 ]]; then
        echo No dynamips images found
    else
        n=1
        while read -r line; do
            echo "File $n : $line"
            n=$((n + 1))
        done <$filename2_dynamips_images
    fi

    echo -e "\n${GREEN}--- qemu images ---${NO_COLOR}"
    if [[ QEMU_FLAG -eq 1 ]]; then
        echo No qemu images found
    else
        n=1
        while read -r line; do
            echo "File $n : $line"
            n=$((n + 1))
        done <$filename3_qemu_images
    fi

    echo -e "\n${GREEN}--- docker images ---${NO_COLOR}"
    if [[ DOCKER_FLAG -eq 1 ]]; then
        echo No docker images found
    else
        n=1
        while read -r line; do
            echo "File $n : $line"
            n=$((n + 1))
        done <$filename4_docker_images
    fi

    STR_BIN="\nDownload BIN images for this lab"
    echo -e "\033[32m$STR_BIN\033[0m"
    if [[ BIN_FLAG -eq 1 ]]; then
        echo -
    else
        download_lab_iol_images "$file"
    fi

    STR_DYNAMIPS="\nDownload DYNAMIPS images for this lab"
    echo -e "\033[32m$STR_DYNAMIPS\033[0m"
    if [[ DYNAMIPS_FLAG -eq 1 ]]; then
        echo -
    else
        download_lab_dynamips_images
    fi

    STR_QEMU="\nDownload QEMU images for this lab"
    echo -e "\033[32m$STR_QEMU\033[0m"
    if [[ QEMU_FLAG -eq 1 ]]; then
        echo -
    else
        download_lab_qemu_images
    fi

    STR_DOCKER="\nDownload DOCKER images for this lab"
    echo -e "\033[32m$STR_DOCKER\033[0m"
    if [[ DOCKER_FLAG -eq 1 ]]; then
        echo -
    else
        download_lab_docker_images
    fi

    # Remove csv file
    rm "$(pwd)"/"$FILENAME" >/dev/null 2>&1

    # Remove files
    rm /opt/unetlab/labs/iol_images.txt
    rm /opt/unetlab/labs/dynamips_images.txt
    rm /opt/unetlab/labs/qemu_images.txt
    rm /opt/unetlab/labs/docker_images.txt
}

function mylabs_install_lab_images_just_for_only_readable_labs_ALL() {
    LABS_DIR=$1

    # Added some correction when "/" is not found at the end of the provided path (LABS_DIR)
    if ! [[ ${LABS_DIR: -1} == "/" ]]; then LABS_DIR=$LABS_DIR/; fi

    if ! [[ -d $LABS_DIR ]]; then
        echo "Folder $LABS_DIR has not been found"
        echo "Check your full path to the labs"
        exit 0
    fi

    if [[ -z "$(ls -A "$LABS_DIR")" ]]; then
        echo "No labs found at $LABS_DIR in server"
        exit 0
    fi

    declare -a readableLabsArray=()
    for file in "$LABS_DIR"*; do
        if [[ -d $file ]]; then continue; fi # Avoiding folders
        check=$(grep -Pio 'encoding="UTF-8"' "$file")
        SUB="encoding"
        if [[ $check == *"$SUB"* ]]; then
            readableLabsArray+=("$file")
        fi
    done

    N=${#readableLabsArray[@]}

    if [[ $N -eq 0 ]]; then
        STR="No readable labs have been found so there is no way to continue with this command"
        echo -e "${RED}[-]$STR\033[0m"
        exit 0
    fi

    if [[ $N -eq 1 ]]; then
        echo "Starting to download images for $N lab"
    else
        echo "Starting to download images for $N labs"
    fi

    for ((i = 1; i <= N; i++)); do
        echo -e "\n\033[32mLab $i/$N\033[0m"
        ishare2 mylabs $LABS_DIR "$i"
    done

    echo -e "\nDone"
}

function get_lab_list_just_for_only_readable_labs() {
    LABS_DIR=/opt/unetlab/labs/"Your labs from PNETLab Store/"

    if ! [[ -d $LABS_DIR ]]; then
        echo "Folder Your labs from PNETLab Store has not been found"
        echo "This folder is created when a lab from PNETLab Store is downloaded"
        exit 0
    fi

    if [[ -z "$(ls -A "$LABS_DIR")" ]]; then
        echo "No labs found at PNETLab Store folder in server"
        exit 0
    fi

    counter_all_labs_installed_on_server=0
    for file in "$LABS_DIR"*; do
        counter_all_labs_installed_on_server=$((counter_all_labs_installed_on_server + 1))
    done

    echo -e "Labs inside PNETLab Store folder in VM: $counter_all_labs_installed_on_server"

    declare -a readableLabsArray=()
    declare -a authorLabsArray=()

    for file in "$LABS_DIR"*; do
        check=$(grep -Pio 'encoding="UTF-8"' "$file")
        SUB="encoding"
        if [[ $check == *"$SUB"* ]]; then
            readableLabsArray+=("$file")
            author_lab_name=$(grep -Pio '.*author="\K[^"]*' "$file" | sort -u)
            if [[ -z $author_lab_name ]]; then # Author name not specified
                author_lab_name=N/A
            fi
            authorLabsArray+=("$author_lab_name")
        fi
    done

    echo "Labs in plain text: ${#readableLabsArray[@]}"

    if [[ ${#readableLabsArray[@]} -eq 0 ]]; then
        STR="No readable labs have been found so there is no way to continue with this command"
        echo -e "${RED}[-]$STR\033[0m"
        exit 0
    fi

    echo -e "\nList\n"

    counter_for_readable_labs=0

    for f in "${readableLabsArray[@]}"; do
        counter_for_readable_labs=$((counter_for_readable_labs + 1))
        echo -e "$counter_for_readable_labs) ${f##*/} - ${authorLabsArray[$((counter_for_readable_labs - 1))]}"
    done

    echo -e "\nTo install images for a specific lab, use the following command:\n\033[32mishare2 labs <number>\033[0m"
    echo -e "\nTo install images for all of the labs, use the following command:\n\033[32mishare2 labs all\033[0m"
}

function install_lab_images_just_for_only_readable_labs() {
    NUMBER=$1

    LABS_DIR=/opt/unetlab/labs/"Your labs from PNETLab Store/"

    if ! [[ -d $LABS_DIR ]]; then
        echo "Folder Your labs from PNETLab Store has not been found"
        echo "This folder is created when a lab from PNETLab Store is downloaded"
        exit 0
    fi

    if [[ -z "$(ls -A "$LABS_DIR")" ]]; then
        echo "No labs found at PNETLab Store folder in server"
        exit 0
    fi

    declare -a readableLabsArray=()
    for file in "$LABS_DIR"*; do
        check=$(grep -Pio 'encoding="UTF-8"' "$file")
        SUB="encoding"
        if [[ $check == *"$SUB"* ]]; then
            readableLabsArray+=("$file")
        fi
    done

    counter_for_readable_labs=0
    for f in "${readableLabsArray[@]}"; do
        counter_for_readable_labs=$((counter_for_readable_labs + 1))
    done

    if [[ ${#readableLabsArray[@]} -eq 0 ]]; then
        STR="No readable labs have been found so there is no way to continue with this command"
        echo -e "${RED}[-]$STR\033[0m"
        exit 0
    fi

    if [[ $NUMBER -gt $counter_for_readable_labs || $NUMBER -le 0 ]]; then
        if [[ $counter_for_readable_labs -eq 1 ]]; then
            STR="Last parameter must be 1 because you have only one lab"
            echo -e "${YELLOW}$STR${NO_COLOR}"
        else
            STR="Last parameter must be a number between 1 and $counter_for_readable_labs"
            echo -e "${YELLOW}$STR${NO_COLOR}"
        fi

        echo -e
        get_lab_list_just_for_only_readable_labs
        exit 0
    fi

    file=${readableLabsArray[$((NUMBER - 1))]}
    echo -e "File selected: $file"

    #echo -e "\nIOL images"
    iol_images=$(grep -Pio 'type="iol".*image="\K[^"]*' "$file" | sort -u)
    #echo "$iol_images"
    echo "$iol_images" >/opt/unetlab/labs/iol_images.txt

    #echo -e "\nDynamips images"
    dynamips_images=$(grep -Pio 'type="dynamips".*image="\K[^"]*' "$file" | sort -u)
    #echo "$dynamips_images"
    echo "$dynamips_images" >/opt/unetlab/labs/dynamips_images.txt

    #echo -e "\nQemu images"
    qemu_images=$(grep -Pio 'type="qemu".*image="\K[^"]*' "$file" | sort -u)
    #echo "$qemu_images"
    echo "$qemu_images" >/opt/unetlab/labs/qemu_images.txt

    #echo -e "\nDocker images"
    docker_images=$(grep -Pio 'type="docker".*image="\K[^"]*' "$file" | sort -u)
    echo "$docker_images" >/opt/unetlab/labs/docker_images.txt

    filename1_iol_images=/opt/unetlab/labs/iol_images.txt
    filename2_dynamips_images=/opt/unetlab/labs/dynamips_images.txt
    filename3_qemu_images=/opt/unetlab/labs/qemu_images.txt
    filename4_docker_images=/opt/unetlab/labs/docker_images.txt

    BIN_FLAG=0
    if ! grep -q '[^[:space:]]' $filename1_iol_images; then BIN_FLAG=1; fi

    DYNAMIPS_FLAG=0
    if ! grep -q '[^[:space:]]' $filename2_dynamips_images; then DYNAMIPS_FLAG=1; fi

    QEMU_FLAG=0
    if ! grep -q '[^[:space:]]' $filename3_qemu_images; then QEMU_FLAG=1; fi

    DOCKER_FLAG=0
    if ! grep -q '[^[:space:]]' $filename4_docker_images; then DOCKER_FLAG=1; fi

    echo -e "\nImages found on lab"

    echo -e "${GREEN}--- bin images ---${NO_COLOR}"
    if [[ BIN_FLAG -eq 1 ]]; then
        echo No bin images found
    else
        n=1
        while read -r line; do
            echo "File $n : $line"
            n=$((n + 1))
        done <$filename1_iol_images
    fi

    echo -e "\n${GREEN}--- dynamips images ---${NO_COLOR}"
    if [[ DYNAMIPS_FLAG -eq 1 ]]; then
        echo No dynamips images found
    else
        n=1
        while read -r line; do
            echo "File $n : $line"
            n=$((n + 1))
        done <$filename2_dynamips_images
    fi

    echo -e "\n${GREEN}--- qemu images ---${NO_COLOR}"
    if [[ QEMU_FLAG -eq 1 ]]; then
        echo No qemu images found
    else
        n=1
        while read -r line; do
            echo "File $n : $line"
            n=$((n + 1))
        done <$filename3_qemu_images
    fi

    echo -e "\n${GREEN}--- docker images ---${NO_COLOR}"
    if [[ DOCKER_FLAG -eq 1 ]]; then
        echo No docker images found
    else
        n=1
        while read -r line; do
            echo "File $n : $line"
            n=$((n + 1))
        done <$filename4_docker_images
    fi

    STR_BIN="\nDownload BIN images for this lab"
    echo -e "\033[32m$STR_BIN\033[0m"
    if [[ BIN_FLAG -eq 1 ]]; then
        echo -
    else
        download_lab_iol_images "$file"
    fi

    STR_DYNAMIPS="\nDownload DYNAMIPS images for this lab"
    echo -e "\033[32m$STR_DYNAMIPS\033[0m"
    if [[ DYNAMIPS_FLAG -eq 1 ]]; then
        echo -
    else
        download_lab_dynamips_images
    fi

    STR_QEMU="\nDownload QEMU images for this lab"
    echo -e "\033[32m$STR_QEMU\033[0m"
    if [[ QEMU_FLAG -eq 1 ]]; then
        echo -
    else
        download_lab_qemu_images
    fi

    STR_DOCKER="\nDownload DOCKER images for this lab"
    echo -e "\033[32m$STR_DOCKER\033[0m"
    if [[ DOCKER_FLAG -eq 1 ]]; then
        echo -
    else
        download_lab_docker_images
    fi

    # Remove csv file
    rm "$(pwd)"/"$FILENAME" >/dev/null 2>&1

    # Remove files
    rm /opt/unetlab/labs/iol_images.txt
    rm /opt/unetlab/labs/dynamips_images.txt
    rm /opt/unetlab/labs/qemu_images.txt
    rm /opt/unetlab/labs/docker_images.txt
}

function install_lab_images_just_for_only_readable_labs_ALL() {
    LABS_DIR=/opt/unetlab/labs/"Your labs from PNETLab Store/"

    if ! [[ -d $LABS_DIR ]]; then
        echo "Folder Your labs from PNETLab Store has not been found"
        echo "This folder is created when a lab from PNETLab Store is downloaded"
        exit 0
    fi

    if [[ -z "$(ls -A "$LABS_DIR")" ]]; then
        echo "No labs found at PNETLab Store folder in server"
        exit 0
    fi

    declare -a readableLabsArray=()
    for file in "$LABS_DIR"*; do
        check=$(grep -Pio 'encoding="UTF-8"' "$file")
        SUB="encoding"
        if [[ $check == *"$SUB"* ]]; then
            readableLabsArray+=("$file")
        fi
    done

    N=${#readableLabsArray[@]}

    if [[ $N -eq 0 ]]; then
        STR="No readable labs have been found so there is no way to continue with this command"
        echo -e "${RED}[-]$STR\033[0m"
        exit 0
    fi

    if [[ $N -eq 1 ]]; then
        echo "Starting to download images for $N lab"
    else
        echo "Starting to download images for $N labs"
    fi

    for ((i = 1; i <= N; i++)); do
        echo -e "\n\033[32mLab $i/$N\033[0m"
        ishare2 labs "$i"
    done

    echo -e "\nDone"
}

function corrections_for_bin_images_in_lab_function() {
    BIN_NAME=$1
    LAB_PATH=$2

    if [[ $BIN_NAME = "i86_Linux-L2-Adventerpisek9-mx.SSA.high_iron_20190423.bin" ]]; then
        OLD_FILENAME="i86_Linux-L2-Adventerpisek9-mx.SSA.high_iron_20190423.bin"
        NEW_FILENAME="i86bi_linux_l2-adventerprisek9-ms.SSA.high_iron_20190423.bin"
        # Bad spelling: 4 errors
        # 1) i86 should be i86bi (bi is missing)
        # 2) Adventerpisek9 should be Adventerprisek9 (r letter is missing)
        # 3) i86_Linux should be i86bi_linux_l2 (L in Linux should be in lowercase, "bi" missing case and change template)
        # 4) -mx should be -ms (not mx but ms)

        BIN_NAME=$NEW_FILENAME
        echo -e "\nImage filename changed from:\n$OLD_FILENAME"
        echo -e "to\n$NEW_FILENAME\n"

        echo "Changing the filename image inside .unl lab file"
        sed -i -e 's/'$OLD_FILENAME'/'$NEW_FILENAME'/g' "$LAB_PATH"
        echo -e "Changing: OK\n"
    fi

    if [[ $BIN_NAME = "L3-ADVENTERPRISEK9-M-15.4-2T.bin" ]]; then
        OLD_FILENAME="L3-ADVENTERPRISEK9-M-15.4-2T.bin"
        NEW_FILENAME="i86bi_linux_l3-L3-ADVENTERPRISEK9-M-15.4-2T.bin"
        # Bad spelling: 1 error
        # 1) L3 is not a yml valid template (There is not a L3.yml available)
        # So, filename must be i86bi_linux_l3 (for i86bi_linux_l3.yml)

        # BIN_NAME="L3-ADVENTERPRISEK9-M-15.4-2T.bin" # This is the old filename to download it in this case
        # echo -e "\nImage filename changed from:\n$OLD_FILENAME"
        # echo -e "to\n$NEW_FILENAME\n"

        echo "Changing the filename image inside .unl lab file"
        sed -i -e 's/'$OLD_FILENAME'/'$NEW_FILENAME'/g' "$LAB_PATH"
        echo -e "Changing: OK"
    fi
}

function download_lab_iol_images() {
    LAB_PATH=$1

    filename1=/opt/unetlab/labs/iol_images.txt
    n=1
    while read -r line; do
        n=$((n + 1))

        BIN_NAME=$line
        FILENAME=BIN_URL.csv
        rm "$(pwd)"/$FILENAME >/dev/null 2>&1
        URL=$BIN_URL
        wget --connect-timeout 5 -O $FILENAME "$URL" >/dev/null 2>&1
        FLAG=0

        corrections_for_bin_images_in_lab_function "$BIN_NAME" "$LAB_PATH"

        while IFS=',' read -r col1 col2 col3 col4 col5; do
            if [[ "$col2" == "$BIN_NAME" ]]; then
                FLAG=1
                NUMBER_TO_DOWNLOAD=$col1
                ishare2 pull bin "$NUMBER_TO_DOWNLOAD"
            fi
        done <$FILENAME

        if [[ "$col2" == "$BIN_NAME" ]]; then
            FLAG=1
            NUMBER_TO_DOWNLOAD=$col1
            ishare2 pull bin "$NUMBER_TO_DOWNLOAD"
        fi

        if [[ $FLAG -eq 0 ]]; then
            STR="(BIN) WARNING: Image $BIN_NAME has not been found"
            echo -e "${YELLOW}$STR${NO_COLOR}"
        fi
    done <$filename1
    rm "$(pwd)"/$FILENAME >/dev/null 2>&1
}

function download_lab_dynamips_images() {
    filename1=/opt/unetlab/labs/dynamips_images.txt
    n=1
    while read -r line; do
        n=$((n + 1))

        DYNAMIPS_NAME=$line
        FILENAME=DYNAMIPS_URL.csv
        rm "$(pwd)"/$FILENAME >/dev/null 2>&1
        URL=$DYNAMIPS_URL
        wget --connect-timeout 5 -O $FILENAME "$URL" >/dev/null 2>&1
        FLAG=0
        while IFS=',' read -r col1 col2 col3 col4 col5; do
            if [[ "$col2" == "$DYNAMIPS_NAME" ]]; then
                FLAG=1
                NUMBER_TO_DOWNLOAD=$col1
                ishare2 pull dynamips "$NUMBER_TO_DOWNLOAD"
            fi
        done <$FILENAME

        if [[ "$col2" == "$DYNAMIPS_NAME" ]]; then
            FLAG=1
            NUMBER_TO_DOWNLOAD=$col1
            ishare2 pull dynamips "$NUMBER_TO_DOWNLOAD"
        fi

        if [[ $FLAG -eq 0 ]]; then
            STR="(DYNAMIPS) WARNING: Image $DYNAMIPS_NAME has not been found"
            echo -e "${YELLOW}$STR${NO_COLOR}"
        fi
    done <$filename1
    rm "$(pwd)"/$FILENAME >/dev/null 2>&1
}

function download_lab_qemu_images() {
    filename1=/opt/unetlab/labs/qemu_images.txt
    n=1
    while read -r line; do
        #echo "Line No. $n : $line"
        n=$((n + 1))

        QEMU_NAME=$line
        FILENAME=QEMU_URL.csv
        rm "$(pwd)"/$FILENAME >/dev/null 2>&1
        URL=$QEMU_URL
        wget --connect-timeout 5 -O $FILENAME "$URL" >/dev/null 2>&1
        FLAG=0

        corrections_for_qemu_images_in_lab_function "$QEMU_NAME"

        while IFS=',' read -r col1 col2 col3 col4 col5; do
            if [[ "$col2" == "$QEMU_NAME" ]]; then
                FLAG=1
                NUMBER_TO_DOWNLOAD=$col1
                ishare2 pull qemu "$NUMBER_TO_DOWNLOAD"
            fi
        done <$FILENAME

        if [[ "$col2" == "$QEMU_NAME" ]]; then
            FLAG=1
            NUMBER_TO_DOWNLOAD=$col1
            ishare2 pull qemu "$NUMBER_TO_DOWNLOAD"
        fi

        if [[ $FLAG -eq 0 ]]; then
            STR="(QEMU) WARNING: Image $QEMU_NAME has not been found"
            echo -e "${YELLOW}$STR${NO_COLOR}"
        fi
    done <$filename1
    rm "$(pwd)"/$FILENAME >/dev/null 2>&1
}

function check_docker_service_status() {
    if service docker status | grep -q "active (running)"; then
        return 0 # 0 means "no failures"
    fi

    if service docker status | grep -q "inactive (dead)"; then
        echo -e "${RED}Detected: Docker service is down. Trying to restart it${NO_COLOR}"
        service docker restart
    fi

    if service docker status | grep -q "active (running)"; then
        echo -e "${GREEN}Docker service has been restarted successfully${NO_COLOR}"
        return 0 # 0 means "no failures"
    else
        echo -e "${RED}There was a problem trying to start docker service${NO_COLOR}"
        echo -e "Information about service docker status command:\n"
        service docker status
        #return 1 # 1 means failure
    fi
}

function list_dockers() {
    echo -e "\nDocker images in server"
    docker images
}

function count_dockers() {
    data=$(docker images | wc -l)
    docker_count=$((data - 1))

    if [[ $docker_count -eq 1 ]]; then
        echo -e "\n$docker_count docker image found in server"
    else
        echo -e "\n$docker_count docker images found in server"
    fi
}

function corrections_for_docker_images_in_lab_function() {
    DOCKER_NAME=$1
    LAB_PATH=$2

    declare -a array=(
        "eve-ostinato"
        "eve-ostinato-bionic"
        "eve-ostinato-focal"
        "eve-dind"
        "eve-dind-focal"
        "eve-chrome"
        "eve-chrome-bionic"
        "eve-chrome-focal"
        "eve-firefox"
        "eve-firefox-bionic"
        "eve-firefox-focal"
        "eve-desktop"
        "eve-desktop-bionic"
        "eve-desktop-focal"
        "eve-gui-server"
        "eve-gui-server-bionic"
        "eve-gui-server-focal"
        "eve-wireshark"
        "eve-wireshark-bionic"
        "eve-wireshark-focal"
        "eve-kali"
        "eve-kali-large"
        "eve-napalm-focal"
        "eve-ansible-focal"
        "dockergui-rdp"
        "eve-gui-server:latest"
        "eve-gui-server-bionic:latest"
    )

    for i in "${array[@]}"; do
        if [[ $DOCKER_NAME == $i ]]; then
            OLD_FILENAME=$DOCKER_NAME
            NEW_FILENAME=eveng/$DOCKER_NAME

            DOCKER_NAME=$NEW_FILENAME
            echo -e "\nDocker image name changed from:\n$OLD_FILENAME"
            echo -e "to\n$NEW_FILENAME\n"

            echo "Changing docker image name inside .unl lab file"
            echo Lab file: "$LAB_PATH"
            sed -i -e s+$OLD_FILENAME+$NEW_FILENAME+g "$LAB_PATH"
            echo -e "Changing: OK\n"
        fi
    done
}

function download_lab_docker_images() {
    filename1=/opt/unetlab/labs/docker_images.txt

    # Checking docker service status before pull any docker image
    if check_docker_service_status $1; then # When 0 is returned
        while read -r line; do
            DOCKER_NAME=$line

            corrections_for_docker_images_in_lab_function $DOCKER_NAME "$LAB_PATH"

            STR="Docker requested: "
            echo -e "\033[33m$STR\033[0m $DOCKER_NAME"

            docker pull "$DOCKER_NAME"
        done <$filename1
    fi

    list_dockers
    count_dockers
}

function check_ishare2_version_file_exists() {
    # Check if file is empty or not exists or different from installed $VERSION
    if [[ ! -s $ISHARE2_DIR/ishare2_version ]] || [[ $(cat $ISHARE2_DIR/ishare2_version) != "$VERSION" ]]; then
        echo $VERSION >$ISHARE2_DIR/ishare2_version
    fi
}

function check_ishare2_gui_version_file_exists() {
    if ! [[ -e $ISHARE2_DIR/ishare2_gui_version ]]; then
        echo -n "$(curl -s $URL_ISHARE2_GUI_VERSION)" >$ISHARE2_DIR/ishare2_gui_version
    fi
}

function upgrade_ishare2() {
    LOCAL_VALUE=$(cat $ISHARE2_DIR/ishare2_version)
    REMOTE_VALUE=$(curl -s $URL_VERSION)

    if [[ $LOCAL_VALUE == "$REMOTE_VALUE" ]]; then
        echo "${YELLOW}[+] ishare2 $REMOTE_VALUE is currently the newest version available. ${NO_COLOR}"
        exit 0
    fi

    rm /usr/sbin/ishare2
    wget -O /usr/sbin/ishare2 $URL_ISHARE2 >/dev/null 2>&1
    # Check if wget threw an error
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error downloading ishare2. Please, check your internet connection. ${NO_COLOR}"
        exit 1
    fi
    # Check if the file is empty
    if [[ ! -s ishare2 ]]; then
        echo "${RED}[-] Error downloading ishare2. Please, check your internet connection. ${NO_COLOR}"
        exit 1
    fi
    echo "Downloaded latest version of ishare2."
    # Make ishare2 executable
    chmod +x /usr/sbin/ishare2
    # Show success message
    echo "${GREEN}[+] ishare2 was upgraded from $LOCAL_VALUE to $REMOTE_VALUE ${NO_COLOR}"
    rm $ISHARE2_DIR/ishare2_version
    echo "$REMOTE_VALUE" >$ISHARE2_DIR/ishare2_version
}

function menu_ishare2_upgrade_pnetlab() {
    prompt="Please, select an option: "
    options=(
        "(STABLE) Upgrade PNETLab: from 4.2.10 to 5.0.1"
        "(STABLE) Upgrade PNETLab: from any version to 5.3.11"
        "(UNSTABLE) Upgrade to / Install PNETLab 6 (ONLY AVAILABLE FOR UBUNTU 20.04)"
    )

    PS3="$prompt"
    select opt in "${options[@]}" "Exit"; do
        case "$REPLY" in
        1)
            wget -O upgrade.sh "$URL_UPGRADE_PNETLAB_FROM_4_2_10_TO_5_0_1"
            chmod +x upgrade.sh
            bash upgrade.sh
            break
            ;;
        2)
            wget -O upgrade.sh "$URL_UPGRADE_PNETLAB_FROM_any_TO_5_3_11"
            chmod +x upgrade.sh
            bash upgrade.sh
            break
            ;;
        3)
            wget --content-disposition -q --show-progress -O upgrade.sh "$URL_UPGRADE_PNETLAB6_INSTALLER"
            chmod +x upgrade.sh
            bash upgrade.sh
            break
            ;;
        $((${#options[@]} + 1)))
            break
            ;;
        *)
            STR="Invalid option: Select a number from 1 to 3"
            echo -e "${RED}$STR${NO_COLOR}"
            continue
            ;;
        esac
    done
}

function menu_ishare2_upgrade() {
    prompt="Please, select an option: "
    options=(
        "Upgrade ishare2"
        "Upgrade PNETLab"
        "Upgrade ishare2 GUI"
    )

    PS3="$prompt"
    select opt in "${options[@]}" "Exit"; do
        case "$REPLY" in
        1)
            upgrade_ishare2
            break
            ;;
        2)
            menu_ishare2_upgrade_pnetlab
            break
            ;;
        3)
            ishare2 gui download
            break
            ;;
        $((${#options[@]} + 1)))
            break
            ;;
        *)
            STR="Invalid option: Select a number from 1 to 4"
            echo -e "${RED}$STR${NO_COLOR}"
            continue
            ;;
        esac
    done
}

function show_changelog() {
    FILE=/root/CHANGELOG.md
    if [[ -e $FILE ]]; then rm $FILE; fi

    DATA="$(wget -q $URL_CHANGELOG_MD -P /root)"
    head -n 15 $FILE
    rm $FILE
}

function ishare2_gui_install() {
    ISHARE2_GUI_DIR=/opt/ishare2/gui
    echo -e "${GREEN}[+] ishare2 GUI is being downloaded and installed. Please, wait until process is done...${NO_COLOR}"
    echo -e "${YELLOW}[!] Stopping ishare2 GUI service...${NO_COLOR}"
    systemctl stop ishare2_gui.service
    if [[ ! -d $ISHARE2_GUI_DIR ]]; then
        mkdir -p $ISHARE2_GUI_DIR
    fi
    if [[ -d $ISHARE2_GUI_DIR ]]; then
        read -p "Found a previous installation of ishare2 GUI. Are you sure you want to remove it? [y/n]: " -n 1 -r
        echo ""
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            echo -e "${GREEN}Removing previous installation of ishare2 GUI...${NO_COLOR}"
            rm -rf $ISHARE2_GUI_DIR/*
            rm -rf $ISHARE2_GUI_DIR/.*
            # remove systemd service
            echo -e "${YELLOW}[!] Removing ishare2 GUI systemd service...${NO_COLOR}"
            systemctl disable ishare2_gui.service
            rm /etc/systemd/system/ishare2_gui.service
        else
            echo -e "${RED}[-] ishare2 GUI installation was cancelled. ${NO_COLOR}"
            exit 1
        fi
    fi

    echo -e "${GREEN}[+] Downloading ishare2 GUI...${NO_COLOR}"
    download_file_wget "$URL_GUI_APP_ZIP" "$ISHARE2_GUI_DIR/app.zip"

    # unzip
    echo -e "${GREEN}[+] Unzipping ishare2 GUI files...${NO_COLOR}"
    unzip -o -q "$ISHARE2_GUI_DIR/app.zip" -d "$ISHARE2_GUI_DIR"
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error unzipping ishare2 GUI. The file may be corrupted. ${NO_COLOR}"
        echo "${RED}[-] Please check your internet connection and try again. ${NO_COLOR}"
        exit 1
    fi
    # move files
    echo -e "${GREEN}[+] Moving files... ${NO_COLOR}"
    mv $ISHARE2_GUI_DIR/ishare2-web-gui-master/* $ISHARE2_GUI_DIR
    # move files starting with a dot if any
    mv $ISHARE2_GUI_DIR/ishare2-web-gui-master/.* $ISHARE2_GUI_DIR
    rmdir $ISHARE2_GUI_DIR/ishare2-web-gui-master

    rm $ISHARE2_GUI_DIR/app.zip

    echo -e "${GREEN}[+] Installing ishare2 GUI requirements...${NO_COLOR}"
    # Make sure pip3 is installed
    apt-get install -y python3-pip
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error installing pip3. ${NO_COLOR}"
        echo "${RED}[-] Please install pip3 manually and try again. ${NO_COLOR}"
        exit 1
    fi

    # Make sure venv is installed
    apt-get install -y python3-venv
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error installing venv. ${NO_COLOR}"
        echo "${RED}[-] Please install venv manually and try again. ${NO_COLOR}"
        echo "${RED}[-] You can find more information here: https://docs.python.org/3/library/venv.html ${NO_COLOR}"
        exit 1
    fi

    # Make venv for ishare2 GUI
    python3 -m venv $ISHARE2_GUI_DIR/venv
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error creating venv for ishare2 GUI. ${NO_COLOR}"
        echo "${RED}[-] Please read previous logs for troubleshooting. ${NO_COLOR}"
        exit 1
    fi

    # Install requirements
    $ISHARE2_GUI_DIR/venv/bin/pip install -r $ISHARE2_GUI_DIR/requirements.txt
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error installing ishare2 GUI requirements. ${NO_COLOR}"
        echo "${RED}[-] Please read previous logs for troubleshooting. ${NO_COLOR}"
        exit 1
    fi

    # Create systemd service to run ishare2 GUI
    echo -e "${GREEN}[+] Creating systemd service to run ishare2 GUI...${NO_COLOR}"
    cat >/etc/systemd/system/ishare2_gui.service <<EOL
[Unit]
Description=ishare2 GUI Web App
After=network.target

[Service]
User=root
Group=root
WorkingDirectory=/opt/ishare2/gui
ExecStart=/opt/ishare2/gui/venv/bin/uvicorn main:app --workers 4 --host 0.0.0.0 --port 5000
Restart=always

[Install]
WantedBy=multi-user.target
EOL

    # Enable and start ishare2 GUI service
    echo -e "${GREEN}[+] Enabling and starting ishare2 GUI service...${NO_COLOR}"
    read -p "Do you want to start ishare2 GUI on boot? [y/n]: " -n 1 -r
    echo ""
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        systemctl enable ishare2_gui.service
    fi
    systemctl start ishare2_gui.service
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error starting ishare2 GUI service. ${NO_COLOR}"
        echo "${RED}[-] Please see the logs for troubleshooting. Run: systemctl status ishare2_gui.service ${NO_COLOR}"
        exit 1
    fi
    echo -e "${GREEN}[!] ishare2 GUI was installed successfully. ${NO_COLOR}"
    echo -e "${GREEN}You can access ishare2 GUI at: http://<server_ip>:5000 or http://localhost:5000 ${NO_COLOR}"
    echo -e "${GREEN}Additionally, you can use the following commands to manage ishare2 GUI: ${NO_COLOR}"
    echo -e "${GREEN}   ishare2 gui start: Start ishare2 GUI service ${NO_COLOR}"
    echo -e "${GREEN}   ishare2 gui stop: Stop ishare2 GUI service ${NO_COLOR}"
    echo -e "${GREEN}   ishare2 gui restart: Restart ishare2 GUI service ${NO_COLOR}"
    echo -e "${GREEN}   systemctl ishare2_gui status: Check ishare2 GUI service status ${NO_COLOR}"
}

function ishare2_gui_start() {
    systemctl start ishare2_gui.service
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error starting ishare2 GUI service. ${NO_COLOR}"
        echo "${RED}[-] Please see the logs for troubleshooting. Run: systemctl status ishare2_gui.service ${NO_COLOR}"
        exit 1
    fi
}

function ishare2_gui_stop() {
    systemctl stop ishare2_gui.service
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error stopping ishare2 GUI service. ${NO_COLOR}"
        echo "${RED}[-] Please see the logs for troubleshooting. Run: systemctl status ishare2_gui.service ${NO_COLOR}"
        exit 1
    fi
}

function ishare2_gui_restart() {
    systemctl restart ishare2_gui.service
    if [[ $? -ne 0 ]]; then
        echo "${RED}[-] Error restarting ishare2 GUI service. ${NO_COLOR}"
        echo "${RED}[-] Please see the logs for troubleshooting. Run: systemctl status ishare2_gui.service ${NO_COLOR}"
        exit 1
    fi
}

function general_available_list() {
    TYPE=$1
    FILENAME=$ISHARE2_DIR/"$TYPE".csv

    echo -e "\n$TYPE available images list\n"

    if [[ $TYPE == "QEMU" ]]; then
        awk -F, '{print $1,$2,$3,$4}' "$FILENAME" | column -t
    else # [[ $TYPE == "DYNAMIPS" || $TYPE == "BIN" ]]
        awk -F, '{print $1,$2,$4,$5}' "$FILENAME" | column -t
    fi

    echo -e "\nTo pull an image, use the following command: \033[32mishare2 pull ${TYPE,,} <number>\033[0m"
}

function generate_a_new_license() {
    BIN_PATH="/opt/unetlab/addons/iol/bin/"

    PYTHON_FILE=$BIN_PATH"CiscoIOUKeygen.py"
    PERL_FILE=$BIN_PATH"keepalive.pl"

    if [[ -e $PYTHON_FILE ]]; then rm $PYTHON_FILE; fi

    wget -O $PYTHON_FILE $URL_CISCO_IOU_KEYGEN_PY >/dev/null 2>&1
    python $PYTHON_FILE >/dev/null 2>&1

    if ! [[ -e $PERL_FILE ]]; then
        wget -O $PERL_FILE $URL_KEEPALIVE_PL >/dev/null 2>&1
    fi
    echo "Done"
}

function download_1_file_bin_or_dynamips() {
    FILES_COUNTER=$1
    NAME=$2
    LINK=$3
    SIZE=$4
    UNIT=$5
    TYPE=$6

    echo -e "Starting to download $FILES_COUNTER file..."

    STR="\n${YELLOW}File requested:${NO_COLOR}"
    echo -e "$STR $NAME"
    STR="${YELLOW}Size:${NO_COLOR}"
    echo -e "$STR $SIZE $UNIT\n"
    echo -e "Downloading from $LINK\n"

    if [[ $TYPE = "dynamips" ]]; then
        mkdir -p /opt/unetlab/addons/dynamips
        # set save path and name
        save_path="/opt/unetlab/addons/dynamips"
        download_file_aria2 "$LINK" "$save_path" "$NAME"
    fi

    if [[ $TYPE = "bin" ]]; then
        mkdir -p /opt/unetlab/addons/iol/bin
        # set save path and name
        save_path="/opt/unetlab/addons/iol/bin"
        download_file_aria2 "$LINK" "$save_path" "$NAME"
    fi
}

function download_1_file_qemu() {
    FILES_COUNTER=$1
    FOLDERNAME=$2
    SIZE=$3
    UNIT=$4
    NAME=$5
    LINK=$6

    echo -e "\nStarting to download $FILES_COUNTER file..."

    echo -e "\n\033[33mFolder requested:\033[0m $FOLDERNAME (""$SIZE"" ""$UNIT"")"
    echo -e "\nFile requested:\n  $NAME - $SIZE $UNIT\n"

    save_path="/opt/unetlab/addons/qemu/$FOLDERNAME"
    download_file_aria2 "$LINK" "$save_path" "$NAME"
}

function download_multiple_files_qemu() {
    FILES_COUNTER=$1
    FOLDERNAME=$2
    SIZE=$3
    UNIT=$4
    myArray=$5

    echo -e "Starting to download $FILES_COUNTER files..."

    echo -e "\n\033[33mFolder requested:\033[0m $FOLDERNAME (""$SIZE"" ""$UNIT"")"

    for ((c = 1; c <= FILES_COUNTER; c++)); do
        echo -e "\nFile $c/$FILES_COUNTER"
        save_path="/opt/unetlab/addons/qemu/$FOLDERNAME"
        download_file_aria2 "${myArray[c - 1]}" "$save_path"
    done
}

function pull_all_iol_images() {
    FILENAME="$ISHARE2_DIR/BIN.csv"

    while IFS=',' read -r col1 _ _ _ _; do
        N=$col1
    done <$FILENAME
    N=$col1

    echo "Starting to download $N bin files"

    for ((i = 1; i <= N; i++)); do
        echo -e "\nFile $i/$N"
        ishare2 pull bin "$i"
    done

    echo -e "\nFinished"
}

function pull_all_dynamips_images() {
    FILENAME="$ISHARE2_DIR/DYNAMIPS.csv"
    while IFS=',' read -r col1 _ _ _ _; do
        N=$col1
    done <$FILENAME
    N=$col1

    echo "Starting to download $N dynamips files"

    for ((i = 1; i <= N; i++)); do
        echo -e "\nFile $i/$N"
        ishare2 pull dynamips "$i"
    done

    echo -e "\nFinished"
}

function pull_dynamips() {
    PARAMETER=$1
    OVERWRITE=$2

    if [[ $PARAMETER = "all" ]]; then
        pull_all_dynamips_images
        exit 0
    fi

    DYNAMIPS_NUMBER=$PARAMETER
    FILENAME=$ISHARE2_DIR"/DYNAMIPS.csv"

    FLAG=0
    while IFS=',' read -r col1 col2 col3 col4 col5; do
        if [[ "$col1" = "$DYNAMIPS_NUMBER" ]]; then
            FLAG=1
            NAME=$col2
            LINK=$col3
            SIZE=$col4
            UNIT=$col5

            corrections_for_dynamips_images "$NAME"
        fi
    done <$FILENAME
    if [[ "$col1" = "$DYNAMIPS_NUMBER" ]]; then
        FLAG=1to $ISHARE2_GUI_DIR
        NAME=$col2
        LINK=$col3
        SIZE=$col4
        UNIT=$col5

        corrections_for_dynamips_images "$NAME"
    fi

    # Remove csv file
    # rm "$(pwd)"/$FILENAME >/dev/null 2>&1

    if [[ $FLAG = 1 ]]; then
        if [[ -e /opt/unetlab/addons/dynamips/"$NAME" && "$OVERWRITE" != "--overwrite" ]]; then
            echo -e "File $NAME already exists in server. Use --overwrite to overwrite it"
            exit 0
        fi

        FILES_COUNTER=1
        download_1_file_bin_or_dynamips $FILES_COUNTER "$NAME" "$LINK" "$SIZE" "$UNIT" dynamips

        # 2. Move downloaded file to /opt/unetlab/addons/dynamips/
        #mv "$NAME" /opt/unetlab/addons/dynamips/
        #Done with -O parameter using wget
        echo -e "\n$NAME was downloaded successfully"

        # 3. Apply fix permissions command
        fix_permissions
    else
        echo "File not found"
        ishare2 search dynamips
    fi
}

function pull_bin() {
    PARAMETER=$1
    OVERWRITE=$2

    if [[ $PARAMETER = "all" ]]; then
        pull_all_iol_images
        exit 0
    fi

    BIN_NUMBER=$PARAMETER

    FILENAME=$ISHARE2_DIR"/BIN.csv"
    FLAG=0
    while IFS=',' read -r col1 col2 col3 col4 col5; do
        if [[ "$col1" = "$BIN_NUMBER" ]]; then
            FLAG=1
            NAME=$col2
            LINK=$col3
            SIZE=$col4
            UNIT=$col5

            corrections_for_iol_images "$NAME"
        fi
    done <$FILENAME

    if [[ "$col1" = "$BIN_NUMBER" ]]; then
        FLAG=1
        NAME=$col2
        LINK=$col3
        SIZE=$col4
        UNIT=$col5

        corrections_for_iol_images "$NAME"
    fi

    # Remove csv file
    # rm "$(pwd)"/$FILENAME >/dev/null 2>&1

    if [[ $FLAG = 1 ]]; then
        if [[ -e /opt/unetlab/addons/iol/bin/"$NAME" && "$OVERWRITE" != "--overwrite" ]]; then
            echo -e "File $NAME already exists in server. Use --overwrite to overwrite it"
            exit 0
        fi

        FILES_COUNTER=1
        download_1_file_bin_or_dynamips $FILES_COUNTER "$NAME" "$LINK" "$SIZE" "$UNIT" bin

        # 2. Move downloaded file to /opt/unetlab/addons/iol/bin/
        #mv "$NAME" /opt/unetlab/addons/iol/bin/
        #Done with -O parameter using wget
        echo -e "\n$NAME was downloaded successfully"

        # 3. Apply fix permissions command
        fix_permissions
    else
        echo "File not found"
        ishare2 search bin
    fi
}

function show_help_info() {
    echo -e "1) For problems, use our Telegram Channel describing your problem and sending a screenshot and/or a video"
    echo -e "\n2) For new files to be uploaded, you can use our Telegram Channel too"
    echo -e "In this case, you can send or ask for new images to be uploaded"
    echo -e "\n3) Using \033[32mishare2 upgrade\033[0m will display a menu that allows users to upgrade ishare2 and PNETLab."
    echo -e "\n4) If CiscoIOUKeygen.py, iourc and/or keepalive.pl files in /opt/unetlab/addons/iol/bin/ are deleted, you can recover them by using \033[32mishare2 relicense\033[0m. This will not affect images in there."
    echo -e "Also, this command when used, will generate a new license file called iourc, needed for bin files"
    echo -e "\n5) Don't cancel a download. In case you do it, you will have to remove incomplete files or folders manually or use the --overwrite parameter."
    echo -e "\n6) The main difference between ${YELLOW}ishare2 labs${NO_COLOR} and ${YELLOW}ishare2 mylabs${NO_COLOR} is that, in the first case, the folder used is the one PNETLab creates when you download a lab from the store and in the second case you are able to select any folder you want in order to download labs"
    echo -e "\nTelegram Channel: https://t.me/NetLabHub"
}

function show_ishare2_usage() {
    # For ishare2
    ISHARE2_VERSION_USAGE=$(cat $ISHARE2_DIR/ishare2_version)

    STR=""
    LOCAL_VALUE=$ISHARE2_VERSION_USAGE
    REMOTE_VALUE=$(curl -s $URL_VERSION)

    if ! [[ $LOCAL_VALUE == "$REMOTE_VALUE" ]]; then
        STR="New ishare2 version available: $REMOTE_VALUE"
    fi

    NEW_VERSION_RESULT=$(echo -e ${YELLOW} $STR ${NO_COLOR})

    # For PNETLab
    data=$(mysql -uroot -ppnetlab -D pnetlab_db -e "SELECT control_value FROM control WHERE control_value>1;" 2>/dev/null)
    pnetlab_info=($data)
    PNETLAB_VERSION_USAGE=${pnetlab_info[1]}

    # For ishare2 GUI
    # ISHARE2_GUI_VERSION_USAGE=$(cat $ISHARE2_DIR/ishare2_gui_version)

    # STR=""
    # LOCAL_VALUE=$ISHARE2_GUI_VERSION_USAGE
    # REMOTE_VALUE=$(curl -s $URL_ISHARE2_GUI_VERSION)

    # if ! [[ $LOCAL_VALUE == "$REMOTE_VALUE" ]]; then
    #     STR="New ishare2 GUI version available: $REMOTE_VALUE"
    # fi

    # NEW_VERSION_RESULT_FOR_ISHARE2_GUI=$(echo -e ${YELLOW} $STR ${NO_COLOR})

    # Message displayed when using ishare2 command
    echo "
Syntax

ishare2 [action] [param1] [param2] [--overwrite]

action:
    search      : Search for images by type
    pull        : Download an image by type and number
    installed   : Show installed images on server
    labs        : Show labs on server and download images for those labs
    mylabs      : Same as labs command but using a customized path to labs
    relicense   : Generate a new iourc license for bin images
    upgrade     : Retrieves a menu that allows users to upgrade ishare2 and PNETLab VM
    changelog   : Show the latest changes made to ishare2
    gui         : Web app to use ishare2 in browser
    test        : Test internet connectivity to required sites (Github, Google Sheets)
    help        : Show useful information

param1:
    type = all, bin, qemu, dynamips, docker or name

param2:
    number = This number can be obtained using ishare2 search <type>

--overwrite:
    Used to overwrite an existing image if it already exists on your system.

Examples:

- ishare2 search <type>
    - ishare2 search all
    - ishare2 search bin
    - ishare2 search qemu
    - ishare2 search dynamips
    - ishare2 search <name>
        Examples:
            - ishare2 search vios
            - ishare2 search win-
            - ishare2 search winserver
            - ishare2 search kali
            - ishare2 search mikro
            - ishare2 search forti
            - ishare2 search nxos
            - ishare2 search vmx
            - ishare2 search esxi
            - ishare2 search palo
            - ishare2 search Licensed
            - More <name> options using ishare2 search all

- ishare2 pull bin <number> [--overwrite]
- ishare2 pull qemu <number> [--overwrite]
- ishare2 pull dynamips <number> [--overwrite]

- ishare2 pull bin all
- ishare2 pull qemu all (Not available for qemu type due to its large size)
- ishare2 pull dynamips all

- ishare2 installed all
- ishare2 installed bin
- ishare2 installed qemu
- ishare2 installed dynamips
- ishare2 installed docker

- ishare2 labs
- ishare2 labs <number>
- ishare2 labs all

- ishare2 mylabs <path>
- ishare2 mylabs <path> <number>
- ishare2 mylabs <path> all

- ishare2 gui install
- ishare2 gui start
- ishare2 gui stop
- ishare2 gui restart

- ishare2 relicense
- ishare2 upgrade
- ishare2 changelog
- ishare2 test
- ishare2 help

ishare2: $ISHARE2_VERSION_USAGE$NEW_VERSION_RESULT
pnetlab: v$PNETLAB_VERSION_USAGE
ishare2 GUI: $ISHARE2_GUI_VERSION_USAGE$NEW_VERSION_RESULT_FOR_ISHARE2_GUI
"
}

function msg_available_options_for_ishare2_search() {
    echo -e "Available options\n"
    echo "- ishare2 search all"
    echo "- ishare2 search qemu"
    echo "- ishare2 search dynamips"
    echo "- ishare2 search bin"
    echo "- ishare2 search <name>"
    echo "  - ishare2 search vios"
    echo "  - ishare2 search win-"
    echo "  - ishare2 search winserver"
    echo "  - ishare2 search kali"
    echo "  - ishare2 search mikro"
    echo "  - ishare2 search forti"
    echo "  - ishare2 search nxos"
    echo "  - ishare2 search vmx"
    echo "  - ishare2 search esxi"
    echo "  - More <name> options using ishare2 search all"
}

function msg_incorrect_argument_or_no_arg_for_ishare2_pull() {
    echo -e "Syntax:\nishare2 pull <type> <number>\n"
    echo "type: bin, qemu or dynamips"
    echo -e "number: ishare2 search <type>\n"
    echo "Example: ishare2 pull qemu 4"
    echo "Example: ishare2 pull dynamips 5"
    echo -e "Example: ishare2 pull bin 6"
}

function tgz_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".tgz"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        file=$(ls "${DIR}"/*"$EXTENSION")
        echo -e "${YELLOW}[-] Extracting: $FOLDERNAME$EXTENSION file... ${NO_COLOR}"
        tar -xf "$file" --strip-components 1 -C "$DIR"
        rm "$file"
        echo -e "${GREEN}[+] Extracted: $DIR. Image ready to use. ${NO_COLOR}"
    fi
}

function tar_gz_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".tar.gz"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        file=$(ls "${DIR}"/*"$EXTENSION")
        echo -e "${YELLOW}[-] Extracting: $FOLDERNAME$EXTENSION file... ${NO_COLOR}"
        tar -xf "$file" --strip-components 1 -C "$DIR"
        rm "$file"
        echo -e "${GREEN}[+] Extracted: $DIR. Image ready to use. ${NO_COLOR}"
    fi
}

function tar_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".tar"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        file=$(ls "${DIR}"/*"$EXTENSION")
        echo -e "${YELLOW}[-] Extracting: $FOLDERNAME$EXTENSION file... ${NO_COLOR}"
        tar -xf "$file" --strip-components 1 -C "$DIR"
        rm "$file"
        echo -e "${GREEN}[+] Extracted: $DIR. Image ready to use. ${NO_COLOR}"
    fi
}

function zip_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".zip"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        file=$(ls "${DIR}"/*"$EXTENSION")
        echo -e "${YELLOW}[-] Extracting: $FOLDERNAME$EXTENSION file... ${NO_COLOR}"
        unzip -a -j "$file" -d "$DIR"
        rm "$file"
        echo -e "${GREEN}[+] Extracted: $DIR. Image ready to use. ${NO_COLOR}"
    fi
}

function rar_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".rar"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        file=$(ls "${DIR}"/*"$EXTENSION")

        if ! [[ -e /usr/bin/unrar ]]; then
            apt -qq update >/dev/null 2>&1 && apt -qq install --assume-yes unrar >/dev/null 2>&1
        fi

        echo -e "${YELLOW}[-] Extracting: $FOLDERNAME$EXTENSION file... ${NO_COLOR}"
        unrar e "$file" "$DIR" >/dev/null 2>&1
        echo -e "${GREEN}[+] Extracted: $DIR. Image ready to use. ${NO_COLOR}"
        rm "$file"
    fi
}

function ova_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".ova"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        COMPRESSED_FILE=$(ls "${DIR}"/*"$EXTENSION")
        echo -e "${YELLOW}[-] Extracting: $FOLDERNAME$EXTENSION file... ${NO_COLOR}"
        tar -xvf "$COMPRESSED_FILE" -C "$DIR"
        rm "$COMPRESSED_FILE"
        echo -e "${GREEN}[+] Extracted: $DIR. Image ready to use. ${NO_COLOR}"
    fi
}

function iso_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".iso"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        ISO_FILE=$(ls "${DIR}"/*"$EXTENSION")

        if ! [[ "${ISO_FILE: -9}" == "cdrom.iso" ]]; then
            mv "$ISO_FILE" "$DIR"/cdrom.iso # Rename file
        fi

        if [[ $FILES_COUNTER -eq 1 ]]; then
            /opt/qemu/bin/qemu-img create -f qcow2 "$DIR"/virtioa.qcow2 20G
        fi
    fi
}

function yml_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSIONS=(".yml" ".yaml")
    #YML_DIR="/opt/unetlab/html/templates/" # Value passed from set_yml_template_folder_location()

    for ext in "${EXTENSIONS[@]}"; do
        if ls "${DIR}"/*"$ext" &>/dev/null; then
            file=$(ls "${DIR}"/*"$ext" | head -1)
            cp "$file" $YML_DIR
            break
        fi
    done
}

function txt_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSIONS=(".txt" ".md")

    for ELEMENT in "$DIR"/*; do
        for EXTENSION in "${EXTENSIONS[@]}"; do
            if [[ "${ELEMENT: -${#EXTENSION}}" == "$EXTENSION" ]]; then
                echo -e "\nReading file: $ELEMENT\n"
                cat "$ELEMENT"
                echo -e
                break
            fi
        done
    done
}

function sh_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".sh"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        file=$(ls "${DIR}"/*"$EXTENSION")
        chmod +x "$file"
        echo -e "\nExecuting $file"
        bash "$file" "$DIR"
    fi
}

function png_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".png"
    PNG_DIR="/opt/unetlab/html/images/icons/"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        file=$(ls "${DIR}"/*"$EXTENSION")

        # Change .png filename for a Huawei device: from ne5000e.png to ne.png
        if [[ $file == "/opt/unetlab/addons/qemu/huaweine5ke-ne5000e/ne5000e.png" ]]; then
            NEW_PNG_FILENAME="/opt/unetlab/addons/qemu/huaweine5ke-ne5000e/ne.png"
            mv "$file" $NEW_PNG_FILENAME
            file=$NEW_PNG_FILENAME
        fi

        cp "$file" $PNG_DIR
    fi
}

function php_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".php"
    PHP_DIR="/opt/unetlab/html/devices/qemu/"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        file=$(ls "${DIR}"/*"$EXTENSION")
        cp "$file" $PHP_DIR
    fi
}

function vmdk_files_function() {
    FOLDERNAME=$1

    DIR="/opt/unetlab/addons/qemu/$FOLDERNAME"

    EXTENSION=".vmdk"

    if ls "${DIR}"/*"$EXTENSION" &>/dev/null; then
        VMDK_FILE=$(ls "${DIR}"/*"$EXTENSION")

        echo -e "\nConverting .vmdk to .qcow2. It might take a while..."
        /opt/qemu/bin/qemu-img convert -p -f vmdk -O qcow2 "$VMDK_FILE" "$DIR"/hda.qcow2
        echo "File converted successfully"
        rm "$VMDK_FILE"
    fi
}

function check_if_yml_template_is_missing() {
    FOLDERNAME=$1

    #YML_DIR="/opt/unetlab/html/templates/" # Value getted from set_yml_template_folder_location()

    TEMPLATE_NAME="$(cut -d'-' -f1 <<<"$FOLDERNAME")"
    EXTENSION=".yml"

    FULL_TEMPLATE_PATH=$YML_DIR"$TEMPLATE_NAME"$EXTENSION

    if ! [[ -e $FULL_TEMPLATE_PATH ]]; then
        STR="\n ${RED}[-] Template $FULL_TEMPLATE_PATH is missing, so device will not appear in list when adding a new node"
        echo -e "$STR\033[0m"
    fi
}

function corrections_for_iol_images() {
    NAME=$1

    if [[ $NAME = "L2-Adventerprisek9-ms.nov3_2015_high_iron.bin" ]]; then
        NAME="i86bi_linux_l2-L2-Adventerprisek9-ms.nov3_2015_high_iron.bin"

        FILE="$YML_DIR"i86bi_linux_l2.yml
        if ! [[ -e $FILE ]]; then
            wget -O $FILE $URL_I86BI_LINUX_L2_YML >/dev/null 2>&1
        fi
    fi

    if [[ $NAME = "L3-ADVENTERPRISEK9-M-15.4-2T.bin" ]]; then
        NAME="i86bi_linux_l3-L3-ADVENTERPRISEK9-M-15.4-2T.bin"

        FILE="$YML_DIR"i86bi_linux_l3.yml
        if ! [[ -e $FILE ]]; then
            wget -O $FILE $URL_I86BI_LINUX_L3_YML >/dev/null 2>&1
        fi
    fi
}

function corrections_for_qemu_images_in_lab_function() {
    QEMU_NAME=$1

    if [[ $QEMU_NAME = "huaweicx-V800R011" ]]; then QEMU_NAME="cx"; fi
    if [[ $QEMU_NAME = "huaweine40e-ne40e" ]]; then QEMU_NAME="ne40e"; fi
    if [[ $QEMU_NAME = "huaweine5ke-ne5000e" ]]; then QEMU_NAME="ne5000e"; fi
    if [[ $QEMU_NAME = "huaweine9k-ne9000" ]]; then QEMU_NAME="ne9000"; fi
    if [[ $QEMU_NAME = "huaweice6800-ce6800" ]]; then QEMU_NAME="ce6800"; fi
    if [[ $QEMU_NAME = "huaweice12800-ce12800" ]]; then QEMU_NAME="ce12800"; fi
    if [[ $QEMU_NAME = "cips-7.0.8" ]]; then QEMU_NAME="vIPS-7.0.8"; fi
    if [[ $QEMU_NAME = "catalyst8000v-17.07.01a" ]]; then QEMU_NAME="c8000v-17.07.01a"; fi
    if [[ $QEMU_NAME = "linux-kali2020-epiol" ]]; then QEMU_NAME="kali-2020-epiol"; fi
}

function corrections_for_qemu_images() {
    # Delete ,,, characters (if present) at the end of the FILE6LINK variable (6th element to download)
    if [[ "${FILE6LINK: -4}" == *",,,"* ]]; then FILE6LINK=${FILE6LINK::-4}; fi
    if [[ $FOLDERNAME = "cx" ]]; then FOLDERNAME="huaweicx-V800R011"; fi
    if [[ $FOLDERNAME = "ne40e" ]]; then FOLDERNAME="huaweine40e-ne40e"; fi
    if [[ $FOLDERNAME = "ne5000e" ]]; then FOLDERNAME="huaweine5ke-ne5000e"; fi
    if [[ $FOLDERNAME = "ne9000" ]]; then FOLDERNAME="huaweine9k-ne9000"; fi
    if [[ $FOLDERNAME = "ce6800" ]]; then FOLDERNAME="huaweice6800-ce6800"; fi
    if [[ $FOLDERNAME = "ce12800" ]]; then FOLDERNAME="huaweice12800-ce12800"; fi
    if [[ $FOLDERNAME = "vIPS-7.0.8" ]]; then FOLDERNAME="cips-7.0.8"; fi
    if [[ $FOLDERNAME = "c8000v-17.07.01a" ]]; then FOLDERNAME="catalyst8000v-17.07.01a"; fi
    if [[ $FOLDERNAME = "kali-2020-epiol" ]]; then FOLDERNAME="linux-kali2020-epiol"; fi
}

function count_elements_to_download_for_qemu_images() {
    FILES_COUNTER=1
    myArray=("$FILE1LINK")

    if ! [[ "$FILE2NAME" == *"-"* ]]; then
        FILES_COUNTER=2
        myArray=("$FILE1LINK" "$FILE2LINK")
    fi

    if ! [[ "$FILE3NAME" == *"-"* ]]; then
        FILES_COUNTER=3
        myArray=("$FILE1LINK" "$FILE2LINK" "$FILE3LINK")
    fi

    if ! [[ "$FILE4NAME" == *"-" ]]; then
        FILES_COUNTER=4
        myArray=("$FILE1LINK" "$FILE2LINK" "$FILE3LINK" "$FILE4LINK")
    fi

    if ! [[ "$FILE5NAME" == *"-"* ]]; then
        FILES_COUNTER=5
        myArray=("$FILE1LINK" "$FILE2LINK" "$FILE3LINK" "$FILE4LINK" "$FILE5LINK")
    fi

    if ! [[ "$FILE6NAME" == *"-"* ]]; then
        FILES_COUNTER=6
        myArray=("$FILE1LINK" "$FILE2LINK" "$FILE3LINK" "$FILE4LINK" "$FILE5LINK" "$FILE6LINK")
    fi
}

function corrections_for_dynamips_images() {
    NAME=$1

    SUBSTRING="c2600"
    if [[ "$NAME" == *"$SUBSTRING"* ]]; then
        FILE="$YML_DIR"c2600.yml
        wget -O $FILE $URL_C2600_YML >/dev/null 2>&1
    fi

    SUBSTRING="c1760"
    if [[ "$NAME" == *"$SUBSTRING"* ]]; then
        FILE="$YML_DIR"c1760.yml
        wget -O $FILE $URL_C1760_YML >/dev/null 2>&1
    fi
}

function pull_qemu() {
    PARAMETER=$1
    OVERWRITE=$2

    if [[ $PARAMETER = "all" ]]; then
        echo "Feature not available for qemu images due to large size"
        exit 0
    fi

    QEMU_NUMBER=$PARAMETER
    FILENAME=$ISHARE2_DIR"/QEMU.csv"

    FLAG=0
    declare -a myArray=()
    while IFS=',' read -r col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col11 col12 col13 col14 col15 col16; do
        if [[ "$col1" = "$QEMU_NUMBER" ]]; then
            FLAG=1

            #NUMBER=$col1
            FOLDERNAME=$col2
            SIZE=$col3
            UNIT=$col4
            FILE1NAME=$col5
            FILE1LINK=$col6
            FILE2NAME=$col7
            FILE2LINK=$col8
            FILE3NAME=$col9
            FILE3LINK=$col10
            FILE4NAME=$col11
            FILE4LINK=$col12
            FILE5NAME=$col13
            FILE5LINK=$col14
            FILE6NAME=$col15
            FILE6LINK=$col16

            corrections_for_qemu_images
            count_elements_to_download_for_qemu_images
        fi
    done <$FILENAME

    if [[ "$col1" = "$QEMU_NUMBER" ]]; then
        FLAG=1

        #NUMBER=$col1
        FOLDERNAME=$col2
        SIZE=$col3
        UNIT=$col4
        FILE1NAME=$col5
        FILE1LINK=$col6
        FILE2NAME=$col7
        FILE2LINK=$col8
        FILE3NAME=$col9
        FILE3LINK=$col10
        FILE4NAME=$col11
        FILE4LINK=$col12
        FILE5NAME=$col13
        FILE5LINK=$col14
        FILE6NAME=$col15
        FILE6LINK=$col16

        corrections_for_qemu_images
        count_elements_to_download_for_qemu_images
    fi

    # Remove csv file
    # rm "$(pwd)"/$FILENAME >/dev/null 2>&1

    if [[ $FLAG = 1 ]]; then
        if [[ -d /opt/unetlab/addons/qemu/"$FOLDERNAME" && "$OVERWRITE" != "--overwrite" ]]; then
            echo -e "Folder $FOLDERNAME already exists in server. Use --overwrite to overwrite it."
            exit 0
        fi

        mkdir -p /opt/unetlab/addons/qemu/"$FOLDERNAME"/

        #1. Download file requested
        if [[ $FILES_COUNTER -eq 1 ]]; then
            download_1_file_qemu $FILES_COUNTER "$FOLDERNAME" "$SIZE" "$UNIT" "$FILE1NAME" "$FILE1LINK"

            #2. Move file to /opt/unetlab/addons/qemu/<folder>
            # mv "$FILE1NAME" /opt/unetlab/addons/qemu/"$FOLDERNAME"/"$FILE1NAME"
            # ^ No longer needed since it will be downloaded to the correct folder with aria2c -d
        fi

        if [[ $FILES_COUNTER -gt 1 ]]; then
            #echo $FILES_COUNTER
            download_multiple_files_qemu $FILES_COUNTER "$FOLDERNAME" "$SIZE" "$UNIT" "${myArray[@]}"

            #2. Move files to /opt/unetlab/addons/qemu/<folder>
            #Files moved to qemu directory when "download_multiple_files_qemu" is called
            #Achieved by using -P parameter in wget
        fi

        #3. Extensions

        # Decompress files section
        tgz_files_function "$FOLDERNAME"
        tar_gz_files_function "$FOLDERNAME"
        tar_files_function "$FOLDERNAME"
        zip_files_function "$FOLDERNAME"
        rar_files_function "$FOLDERNAME"
        ova_files_function "$FOLDERNAME"
        iso_files_function "$FOLDERNAME"

        # Treat files section
        yml_files_function "$FOLDERNAME"
        txt_files_function "$FOLDERNAME"
        sh_files_function "$FOLDERNAME"
        png_files_function "$FOLDERNAME"
        php_files_function "$FOLDERNAME"
        vmdk_files_function "$FOLDERNAME"

        # 4. Show if .yml template is missing
        check_if_yml_template_is_missing "$FOLDERNAME"

        # 5. Apply fix permissions command
        fix_permissions
    else
        echo -e "${RED}Error: ${NC}No image found with number $QEMU_NUMBER"
        echo -e "Use ${GREEN}ishare2 search qemu${NC} to search for an image"
        # get user input y or n
        read -p "Do you want to search for the image? [y/n] " -n 1 -r
        echo -e # (optional) move to a new line after user input
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            ishare2 search qemu
        fi
    fi
}

function filter_bin() {
    NAME_TO_SEARCH_FOR=$1

    FILENAME=$ISHARE2_DIR"/BIN.csv"

    FLAG_TO_SHOW_RESULTS_BIN=0
    while IFS=',' read -r col1 col2 col3 col4 col5; do
        if grep -q "$NAME_TO_SEARCH_FOR" "$FILENAME"; then
            CMD=$(grep "$NAME_TO_SEARCH_FOR" "$FILENAME")
            FLAG_TO_SHOW_RESULTS_BIN=1
            break
        fi
    done <$FILENAME

    if [[ $FLAG_TO_SHOW_RESULTS_BIN -eq 1 ]]; then
        echo "Number, Name, Link, Size, Unit" >new.csv
        echo "$CMD" >new.csv
        echo -e
        echo "$CMD" | awk -F, '{print $1,$2,$4,$5}' new.csv | column -t

        RESULTS_NUMBER=$(cat <new.csv | wc -l)
        echo -e "\nNumber of results: $((RESULTS_NUMBER - 1))"

        TYPE=BIN
        echo -e "\nTo pull an image, use the following command: \033[32mishare2 pull ${TYPE,,} <number>\033[0m\n"
    fi

    # Remove csv files
    rm "$(pwd)"/new.csv >/dev/null 2>&1
}

function filter_dynamips() {
    NAME_TO_SEARCH_FOR=$1

    FILENAME=$ISHARE2_DIR"/DYNAMIPS.csv"

    FLAG_TO_SHOW_RESULTS_DYNAMIPS=0
    while IFS=',' read -r col1 col2 col3 col4 col5; do
        if grep -q "$NAME_TO_SEARCH_FOR" "$FILENAME"; then
            CMD=$(grep "$NAME_TO_SEARCH_FOR" "$FILENAME")
            FLAG_TO_SHOW_RESULTS_DYNAMIPS=1
            break
        fi
    done <$FILENAME

    if [[ $FLAG_TO_SHOW_RESULTS_DYNAMIPS -eq 1 ]]; then
        echo "Number, Name, Link, Size, Unit" >new.csv
        echo "$CMD" >new.csv
        echo -e
        echo "$CMD" | awk -F, '{print $1,$2,$4,$5}' new.csv | column -t

        RESULTS_NUMBER=$(cat <new.csv | wc -l)
        echo -e "\nNumber of results: $((RESULTS_NUMBER - 1))"

        TYPE=DYNAMIPS
        echo -e "\nTo pull an image, use the following command: \033[32mishare2 pull ${TYPE,,} <number>\033[0m\n"
    fi

    # Remove csv files
    rm "$(pwd)"/new.csv >/dev/null 2>&1
}

function filter_qemu() {
    NAME_TO_SEARCH_FOR=$1

    FILENAME=$ISHARE2_DIR"/QEMU.csv"

    FLAG_TO_SHOW_RESULTS_QEMU=0
    while IFS=',' read -r col1 col2 col3 col4 col5; do
        if grep -q "$NAME_TO_SEARCH_FOR" "$FILENAME"; then
            CMD=$(grep "$NAME_TO_SEARCH_FOR" "$FILENAME")
            FLAG_TO_SHOW_RESULTS_QEMU=1
            break
        fi
    done <$FILENAME

    if [[ $FLAG_TO_SHOW_RESULTS_QEMU -eq 1 ]]; then
        echo "Number, Name, Size, Unit" >new.csv
        echo "$CMD" >new.csv
        echo "$CMD" | awk -F, '{print $1,$2,$3,$4}' new.csv | column -t

        RESULTS_NUMBER=$(cat <new.csv | wc -l)
        echo -e "\nNumber of results: $((RESULTS_NUMBER - 1))"

        TYPE=QEMU
        echo -e "\nTo pull an image, use the following command: \033[32mishare2 pull ${TYPE,,} <number>\033[0m"
    fi

    # Remove temp csv files
    rm "$(pwd)"/new.csv >/dev/null 2>&1
}

function fix_permissions() {
    /opt/unetlab/wrappers/unl_wrapper -a fixpermissions
    if [[ $? -eq 0 ]]; then
        echo -e "\n${GREEN} [+] Fix permissions command has been executed correctly ${NO_COLOR}"
    else
        echo -e "\n${RED} [-] Failed to fix permissions ${NO_COLOR}"
    fi
}

function connection_tests() {
    # Header
    echo -e "${YELLOW}[-] Running connection tests... ${NO_COLOR}"
    # Check if GitHub is reachable
    echo -e "${YELLOW}[-] Checking if GitHub is reachable... ${NO_COLOR}"
    if ping -q -c 1 -W 1 github.com >/dev/null; then
        echo -e "${GREEN}[+] GitHub is reachable. ${NO_COLOR}"
    else
        echo -e "${RED}[-] GitHub is not reachable ${NO_COLOR}"
    fi
    # Check if Google Sheets is reachable
    echo -e "${YELLOW}[-] Checking if Google Sheets is reachable... ${NO_COLOR}"
    if ping -q -c 1 -W 1 docs.google.com >/dev/null; then
        echo -e "${GREEN}[+] Google Sheets is reachable. ${NO_COLOR}"
    else
        echo -e "${RED}[-] Google Sheets is not reachable ${NO_COLOR}"
    fi
    # Checks completed
    echo -e "${YELLOW}[-] Connection tests completed. ${NO_COLOR}"
}

function selector() {
    if [[ "$1" = "search" ]]; then  # ishare2 search
        if [[ "$2" = "all" ]]; then # ishare2 search all
            ishare2 search qemu
            ishare2 search dynamips
            ishare2 search bin
            echo " "
        elif [[ "$2" = "qemu" ]]; then # ishare2 search qemu
            general_available_list QEMU
        elif [[ "$2" = "dynamips" ]]; then # ishare2 search dynamips
            general_available_list DYNAMIPS
        elif [[ "$2" = "bin" ]]; then # ishare2 search bin
            general_available_list BIN
        else # 1) ishare2 search 2) ishare2 search <number> 3) ishare2 search <string>
            if [[ $2 ]]; then
                filter_bin "$2"
                filter_dynamips "$2"
                filter_qemu "$2"
            else
                msg_available_options_for_ishare2_search
            fi
        fi
    elif [[ "$1" = "pull" ]]; then       # ishare2 pull
        if [[ "$2" ]]; then              # check if exists an arg to ishare2 pull x
            if [[ "$2" = "qemu" ]]; then # ishare2 pull qemu
                if [[ "$3" ]]; then      # check if exists an arg to ishare2 pull qemu
                    pull_qemu "$3" "$4"
                else
                    STR="Last parameter not detected"
                    echo -e "${RED}$STR${NO_COLOR}"
                    echo -e "Syntax: ishare2 pull qemu ${YELLOW}<number>${NO_COLOR}"
                fi
            elif [[ "$2" = "dynamips" ]]; then # ishare2 pull dynamips
                if [[ "$3" ]]; then
                    pull_dynamips "$3" "$4"
                else
                    STR="Last parameter not detected"
                    echo -e "${RED}$STR${NO_COLOR}"
                    echo -e "Syntax: ishare2 pull dynamips ${YELLOW}<number>${NO_COLOR}"
                fi
            elif [[ "$2" = "bin" ]]; then # ishare2 pull bin
                if [[ "$3" ]]; then
                    pull_bin "$3" "$4"
                else
                    STR="Last parameter not detected"
                    echo -e "${RED}$STR${NO_COLOR}"
                    echo -e "Syntax: ishare2 pull bin ${YELLOW}<number>${NO_COLOR}"
                fi
            else # ishare2 pull gets an incorrect argument for type (nor dynamips nor bin nor qemu)
                msg_incorrect_argument_or_no_arg_for_ishare2_pull
            fi
        else # when there is not an arg to ishare2 pull
            msg_incorrect_argument_or_no_arg_for_ishare2_pull
        fi
    elif [[ "$1" = "installed" ]]; then # ishare2 installed
        if [[ "$2" ]]; then
            if [[ "$2" = "all" ]]; then
                echo -e "${GREEN}----- QEMU -----${NO_COLOR}"
                ishare2 installed qemu
                echo -e "${GREEN}----- DYNAMIPS -----${NO_COLOR}"
                ishare2 installed dynamips
                echo -e "${GREEN}----- BIN -----${NO_COLOR}"
                ishare2 installed bin
                echo -e "${GREEN}----- DOCKER -----${NO_COLOR}"
                ishare2 installed docker
            elif [[ "$2" = "qemu" ]]; then
                echo -e
                ls -lh -R /opt/unetlab/addons/qemu/
                echo -e
            elif [[ "$2" = "dynamips" ]]; then
                echo -e
                ls -lh -R /opt/unetlab/addons/dynamips/
                echo -e
            elif [[ "$2" = "bin" ]]; then
                echo -e
                ls -lh -R /opt/unetlab/addons/iol/bin/
                echo -e
            elif [[ "$2" = "docker" ]]; then
                list_dockers
                count_dockers
            else
                echo -e "Syntax:\n\nishare2 installed <type>"
                echo -e "${YELLOW}type: all, bin, qemu, dynamips or docker${NO_COLOR}"
            fi
        else
            echo -e "Syntax:\n\nishare2 installed ${YELLOW}<type>${NO_COLOR}"
            echo -e "type: all, bin, qemu, dynamips or docker"
        fi
    elif [[ "$1" = "labs" ]]; then      # ishare2 labs
        if [[ "$2" ]]; then             # ishare2 labs x (x could be "all" or a number)
            if [[ "$2" = "all" ]]; then # ishare2 labs all
                install_lab_images_just_for_only_readable_labs_ALL
                exit 0
            else # ishare2 labs <number>
                install_lab_images_just_for_only_readable_labs "$2"
                exit 0
            fi
        fi
        get_lab_list_just_for_only_readable_labs
    elif [[ $1 == "mylabs" ]]; then # ishare2 mylabs
        if [[ "$2" ]]; then
            if [[ "$3" ]]; then
                if [[ "$3" == "all" ]]; then # ishare2 mylabs <path> all
                    mylabs_install_lab_images_just_for_only_readable_labs_ALL $2 all
                else
                    if ! [[ -z "${3##*[!0-9]*}" ]]; then # ishare2 mylabs <path> <number>
                        mylabs_install_lab_images_just_for_only_readable_labs $2 $3
                    else
                        STR="The last parameter must be a number"
                        echo -e "${RED}$STR${NO_COLOR}"
                        echo -e "ishare2 mylabs <path> ${YELLOW}<number>${NO_COLOR}"
                    fi
                fi
            else # ishare2 mylabs <path>
                mylabs_get_lab_list_just_for_only_readable_labs $2
            fi
        else
            echo -e "Syntax:\n\nishare2 mylabs <path>"
            echo "ishare2 mylabs <path> <number>"
            echo -e "ishare2 mylabs <path> all"
        fi
    elif [[ "$1" = "relicense" ]]; then # ishare2 relicense
        generate_a_new_license
    elif [[ "$1" = "update" ]]; then # ishare2 update
        manual_sources_update
    elif [[ "$1" = "upgrade" ]]; then # ishare2 upgrade
        menu_ishare2_upgrade
    elif [[ "$1" = "changelog" ]]; then # ishare2 changelog
        show_changelog
    elif [[ "$1" = "gui" ]]; then # ishare2 gui
        if [[ "$2" ]]; then
            if [[ "$2" == "install" ]]; then # ishare2 gui download
                ishare2_gui_install
            elif [[ "$2" == "start" ]]; then # ishare2 gui start
                ishare2_gui_start
            elif [[ "$2" == "stop" ]]; then # ishare2 gui stop
                ishare2_gui_stop
            elif [[ "$2" == "restart" ]]; then # ishare2 gui restart
                ishare2_gui_restart
            else
                echo -e "${RED}Bad last argument${NO_COLOR}"
                echo -e "Syntax:\n\nishare2 gui <option>\n"
                echo "ishare2 gui download"
                echo -e "ishare2 gui start"
                echo -e "ishare2 gui stop"
                echo -e "ishare2 gui restart"
            fi
        else
            echo -e "Syntax:\n\nishare2 gui <option>\n"
            echo "ishare2 gui download"
            echo -e "ishare2 gui start"
            echo -e "ishare2 gui stop"
            echo -e "ishare2 gui restart"
        fi
    elif [[ "$1" = "help" ]]; then # ishare2 help
        show_help_info
    elif [[ "$1" = "test" ]]; then # ishare2 test
        connection_tests
    else # when no args are passed to ishare2
        show_ishare2_usage
    fi
}

function main() {
    check_user_is_root
    set_max_log_lines
    check_aria2
    set_url_constants
    download_files_lists
    set_yml_template_folder_location
    check_ishare2_version_file_exists
    check_ishare2_gui_version_file_exists
    selector "$1" "$2" "$3" "$4"
}

main $@
